/*****************************************************************
**                大连理工大学 凌BUG战队
**                **生死有命，富贵在天**
**    没有什么难题是一个通宵解决不了的，如果有那就整两个！
**---------------------------------------------------------------
** 项目名称：   mxdemo_std_robot
** 日    期：   2021-04-15
** 作    者：   MasterWang
**---------------------------------------------------------------
** 文 件 名：   referee_system.c
** 文件说明：   裁判系统协议解析和客户端UI绘制
*****************************************************************/

/*---------------------INCLUDES----------------------*/
#include "referee_system.h"
#include "usart.h"

/*---------------------VARIABLES---------------------*/
//使用CCM数据RAM区(0x10005000-0x10007FFF 12KB)
uint8_t referee_fifo_buf[REFEREE_FIFO_BUF_NUM][REFEREE_FIFO_BUF_LEN] __attribute__((at(0x10005000))) = {0}; //8*1KB

uint8_t fifo_count __attribute__((at(0x10007C00))) = 0;
uint8_t fifo_head_pos __attribute__((at(0x10007C04))) = 0;
uint8_t fifo_tail_pos __attribute__((at(0x10007C08))) = 0;

uint8_t referee_seq_num __attribute__((at(0x10007C10))) = 0;
uint8_t student_interactive_seq __attribute__((at(0x10007C14))) = 0;

//
RobotRefereeStatus_t robot_referee_status __attribute__((at(0x10007000))) = {0};
ClientUIStatus_t client_ui_status __attribute__((at(0x10007800))) = {0};

/*---------------------FUNCTIONS---------------------*/

/***********************************************************************
** 函 数 名： PushToRefereeFIFOBuf()
** 函数说明： 从串口DMA的接收缓冲循环数组中提取数据帧,压入裁判系统协议解析缓冲队列(在UART中断调用)
**---------------------------------------------------------------------
** 输入参数： 串口DMA接收缓冲数组地址,数组最大长度,起始位置,结束位置
** 返回参数： 无
***********************************************************************/
void PushToRefereeFIFOBuf(uint8_t *pdata, uint16_t max_size, uint16_t start_pos, uint16_t end_pos)
{
	uint16_t size;
	
	if(end_pos>=start_pos){size=end_pos-start_pos;}
	else{size=max_size-(start_pos-end_pos);}
	
	if((size>0)&&(fifo_count<REFEREE_FIFO_BUF_NUM))
	{
		//
		referee_fifo_buf[fifo_tail_pos][0]=size>>8;
		referee_fifo_buf[fifo_tail_pos][1]=size;
		
		if(end_pos>start_pos){memcpy(referee_fifo_buf[fifo_tail_pos]+2, pdata+start_pos, size);}
		else{memcpy(referee_fifo_buf[fifo_tail_pos]+2, pdata+start_pos, max_size-start_pos); memcpy(referee_fifo_buf[fifo_tail_pos]+2+(max_size-start_pos), pdata, end_pos);}
		
		//
		fifo_tail_pos=(fifo_tail_pos+1)%REFEREE_FIFO_BUF_NUM;
		fifo_count++;
	}
}

/***********************************************************************
** 函 数 名： ParseRefereeSystemData()
** 函数说明： 裁判系统协议解析(在100Hz定时器中断调用)
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void ParseRefereeSystemData(void)
{
	int16_t remaining_n;
	
	uint8_t *pbuf;
	uint8_t *ptr; //用于float和uint64_t类型数据转换
	
	uint16_t data_len;
	uint16_t cmd;
	
	if(fifo_count>0)
	{
		//
		remaining_n = referee_fifo_buf[fifo_head_pos][0]*256+referee_fifo_buf[fifo_head_pos][1];
		pbuf = referee_fifo_buf[fifo_head_pos]+2;
		
		while(1)
		{
			//
			if((pbuf[0]==0xA5)&&(remaining_n>=5)) //check frame_header & length
			{
				if(Verify_CRC8_Check_Sum(pbuf,5)) //check head_crc8
				{
					data_len=pbuf[2]*256+pbuf[1];
					if(pbuf[3]!=(uint8_t)(referee_seq_num+1)){robot_referee_status.cmd_error_count[0]++;} //seq_num error
					referee_seq_num=pbuf[3];
				
					//
					if(remaining_n>=data_len+9) //5+2+len+2 //check package length
					{
						if(Verify_CRC16_Check_Sum(pbuf,data_len+9)) //check package_crc16
						{
							cmd = pbuf[6]*256+pbuf[5];
							
							//
							if(cmd==0x0201) //10Hz,机器人状态数据
							{
								robot_referee_status.game_robot_status.recv_cnt++;
								robot_referee_status.game_robot_status.robot_id = pbuf[7];
								robot_referee_status.game_robot_status.robot_level = pbuf[8];
								robot_referee_status.game_robot_status.remain_HP = pbuf[10]*256+pbuf[9];
								robot_referee_status.game_robot_status.max_HP = pbuf[12]*256+pbuf[11];
								robot_referee_status.game_robot_status.shooter_id1_17mm_cooling_rate = pbuf[14]*256+pbuf[13];
								robot_referee_status.game_robot_status.shooter_id1_17mm_cooling_limit = pbuf[16]*256+pbuf[15];
								robot_referee_status.game_robot_status.shooter_id1_17mm_speed_limit = pbuf[18]*256+pbuf[17];
								robot_referee_status.game_robot_status.shooter_id2_17mm_cooling_rate = pbuf[20]*256+pbuf[19];
								robot_referee_status.game_robot_status.shooter_id2_17mm_cooling_limit = pbuf[22]*256+pbuf[21];
								robot_referee_status.game_robot_status.shooter_id2_17mm_speed_limit = pbuf[24]*256+pbuf[23];
								robot_referee_status.game_robot_status.shooter_id1_42mm_cooling_rate = pbuf[26]*256+pbuf[25];
								robot_referee_status.game_robot_status.shooter_id1_42mm_cooling_limit = pbuf[28]*256+pbuf[27];
								robot_referee_status.game_robot_status.shooter_id1_42mm_speed_limit = pbuf[30]*256+pbuf[29];
								robot_referee_status.game_robot_status.chassis_power_limit = pbuf[32]*256+pbuf[31];
								robot_referee_status.game_robot_status.mains_power_gimbal_output = pbuf[33];
								robot_referee_status.game_robot_status.mains_power_chassis_output = pbuf[33]>>1;
								robot_referee_status.game_robot_status.mains_power_shooter_output = pbuf[33]>>2;					
							}
							else if(cmd==0x0202) //50Hz,实时功率热量数据
							{
								robot_referee_status.power_heat_data.recv_cnt++;
								robot_referee_status.power_heat_data.chassis_volt = pbuf[8]*256+pbuf[7];
								robot_referee_status.power_heat_data.chassis_current = pbuf[10]*256+pbuf[9];
								ptr=(uint8_t *)&robot_referee_status.power_heat_data.chassis_power; ptr[0]=pbuf[11]; ptr[1]=pbuf[12]; ptr[2]=pbuf[13]; ptr[3]=pbuf[14];
								robot_referee_status.power_heat_data.chassis_power_buffer = pbuf[16]*256+pbuf[15];
								robot_referee_status.power_heat_data.shooter_id1_17mm_cooling_heat = pbuf[18]*256+pbuf[17];
								robot_referee_status.power_heat_data.shooter_id2_17mm_cooling_heat = pbuf[20]*256+pbuf[19];
								robot_referee_status.power_heat_data.shooter_id1_42mm_cooling_heat = pbuf[22]*256+pbuf[21];
							}
							else if(cmd==0x0203) //10Hz,机器人位置数据
							{
								robot_referee_status.game_robot_pos.recv_cnt++;
								ptr=(uint8_t *)&robot_referee_status.game_robot_pos.x; ptr[0]=pbuf[7]; ptr[1]=pbuf[8]; ptr[2]=pbuf[9]; ptr[3]=pbuf[10];
								ptr=(uint8_t *)&robot_referee_status.game_robot_pos.y; ptr[0]=pbuf[11]; ptr[1]=pbuf[12]; ptr[2]=pbuf[13]; ptr[3]=pbuf[14];
								ptr=(uint8_t *)&robot_referee_status.game_robot_pos.z; ptr[0]=pbuf[15]; ptr[1]=pbuf[16]; ptr[2]=pbuf[17]; ptr[3]=pbuf[18];
								ptr=(uint8_t *)&robot_referee_status.game_robot_pos.yaw; ptr[0]=pbuf[19]; ptr[1]=pbuf[20]; ptr[2]=pbuf[21]; ptr[3]=pbuf[22];
							}
							else if(cmd==0x0204) //1Hz,机器人增益数据
							{
								robot_referee_status.buff.recv_cnt++;
								robot_referee_status.buff.power_rune_buff = pbuf[7];
							}
							else if(cmd==0x0205) //10Hz,空中机器人能量状态数据,只有空中机器人主控发送
							{
								robot_referee_status.aerial_robot_energy.recv_cnt++;
								robot_referee_status.aerial_robot_energy.attack_time = pbuf[7];
							}
							else if(cmd==0x0206) //伤害发生后发送,伤害状态数据
							{
								robot_referee_status.robot_hurt.recv_cnt++;
								robot_referee_status.robot_hurt.armor_id = pbuf[7];
								robot_referee_status.robot_hurt.hurt_type = pbuf[7]>>4;
							}
							else if(cmd==0x0207) //子弹发射后发送,实时射击数据
							{
								robot_referee_status.shoot_data.recv_cnt++;
								robot_referee_status.shoot_data.bullet_type = pbuf[7];
								robot_referee_status.shoot_data.shooter_id = pbuf[8];
								robot_referee_status.shoot_data.bullet_freq = pbuf[9];
								ptr=(uint8_t *)&robot_referee_status.shoot_data.bullet_speed; ptr[0]=pbuf[10]; ptr[1]=pbuf[11]; ptr[2]=pbuf[12]; ptr[3]=pbuf[13];
							}
							else if(cmd==0x0208) //1Hz,子弹剩余发射数
							{
								robot_referee_status.bullet_remaining.recv_cnt++;
								robot_referee_status.bullet_remaining.bullet_remaining_num_17mm = pbuf[8]*256+pbuf[7];
								robot_referee_status.bullet_remaining.bullet_remaining_num_42mm = pbuf[10]*256+pbuf[9];
								robot_referee_status.bullet_remaining.coin_remaining_num = pbuf[12]*256+pbuf[11];
							}
							else if(cmd==0x0209) //1Hz,机器人RFID状态数据
							{
								robot_referee_status.rfid_status.recv_cnt++;
								robot_referee_status.rfid_status.rfid_status = pbuf[9]; //(pbuf[12]<<24)+(pbuf[11]<<16)+(pbuf[10]<<8)+pbuf[9];
							}
							else if(cmd==0x020A) //10Hz,飞镖机器人客户端指令数据
							{
								robot_referee_status.dart_client_cmd.recv_cnt++;
								robot_referee_status.dart_client_cmd.dart_launch_opening_status = pbuf[7];
								robot_referee_status.dart_client_cmd.dart_attack_target = pbuf[8];
								robot_referee_status.dart_client_cmd.target_change_time = pbuf[10]*256+pbuf[9];
								robot_referee_status.dart_client_cmd.first_dart_speed = pbuf[11];
								robot_referee_status.dart_client_cmd.second_dart_speed = pbuf[12];
								robot_referee_status.dart_client_cmd.third_dart_speed = pbuf[13];
								robot_referee_status.dart_client_cmd.fourth_dart_speed = pbuf[14];
								robot_referee_status.dart_client_cmd.last_dart_launch_time = pbuf[16]*256+pbuf[15];
								robot_referee_status.dart_client_cmd.operate_launch_cmd_time = pbuf[18]*256+pbuf[17];
							}
							else if(cmd==0x0001) //1Hz,比赛状态数据
							{
								robot_referee_status.game_status.recv_cnt++;
								robot_referee_status.game_status.game_type = pbuf[7];
								robot_referee_status.game_status.game_progress = pbuf[7]>>4;
								robot_referee_status.game_status.stage_remain_time = pbuf[9]*256+pbuf[8];
								ptr=(uint8_t *)&robot_referee_status.game_status.SyncTimeStamp; ptr[0]=pbuf[10]; ptr[1]=pbuf[11]; ptr[2]=pbuf[12]; ptr[3]=pbuf[13]; ptr[4]=pbuf[14]; ptr[5]=pbuf[15]; ptr[6]=pbuf[16]; ptr[7]=pbuf[17];
							}
							else if(cmd==0x0002) //比赛结束后发送,比赛结果数据
							{
								robot_referee_status.game_result.recv_cnt++;
								robot_referee_status.game_result.winner = pbuf[7];
							}
							else if(cmd==0x0003) //1Hz,比赛机器人血量数据
							{
								robot_referee_status.game_robot_HP.recv_cnt++;
								robot_referee_status.game_robot_HP.red_1_robot_HP = pbuf[8]*256+pbuf[7];
								robot_referee_status.game_robot_HP.red_2_robot_HP = pbuf[10]*256+pbuf[9];
								robot_referee_status.game_robot_HP.red_3_robot_HP = pbuf[12]*256+pbuf[11];
								robot_referee_status.game_robot_HP.red_4_robot_HP = pbuf[14]*256+pbuf[13];
								robot_referee_status.game_robot_HP.red_5_robot_HP = pbuf[16]*256+pbuf[15];
								robot_referee_status.game_robot_HP.red_7_robot_HP = pbuf[18]*256+pbuf[17];
								robot_referee_status.game_robot_HP.red_outpost_HP = pbuf[20]*256+pbuf[19];
								robot_referee_status.game_robot_HP.red_base_HP = pbuf[22]*256+pbuf[21];
								robot_referee_status.game_robot_HP.blue_1_robot_HP = pbuf[24]*256+pbuf[23];
								robot_referee_status.game_robot_HP.blue_2_robot_HP = pbuf[26]*256+pbuf[25];
								robot_referee_status.game_robot_HP.blue_3_robot_HP = pbuf[28]*256+pbuf[27];
								robot_referee_status.game_robot_HP.blue_4_robot_HP = pbuf[30]*256+pbuf[29];
								robot_referee_status.game_robot_HP.blue_5_robot_HP = pbuf[32]*256+pbuf[31];
								robot_referee_status.game_robot_HP.blue_7_robot_HP = pbuf[34]*256+pbuf[33];
								robot_referee_status.game_robot_HP.blue_outpost_HP = pbuf[36]*256+pbuf[35];
								robot_referee_status.game_robot_HP.blue_base_HP = pbuf[38]*256+pbuf[37];
							}
							else if(cmd==0x0004) //飞镖发射后发送,飞镖发射状态数据
							{
								robot_referee_status.dart_status.recv_cnt++;
								robot_referee_status.dart_status.dart_belong = pbuf[7];
								robot_referee_status.dart_status.stage_remaining_time = pbuf[9]*256+pbuf[8];
							}
							else if(cmd==0x0005) //1Hz,人工智能挑战赛加成与惩罚区状态
							{
								robot_referee_status.ICRA_buff_debuff_zone_status.recv_cnt++;
								robot_referee_status.ICRA_buff_debuff_zone_status.F1_zone_status = pbuf[7];
								robot_referee_status.ICRA_buff_debuff_zone_status.F1_zone_buff_debuff_status = pbuf[7]>>1;
								robot_referee_status.ICRA_buff_debuff_zone_status.F2_zone_status = pbuf[7]>>4;
								robot_referee_status.ICRA_buff_debuff_zone_status.F2_zone_buff_debuff_status = pbuf[7]>>5;
								robot_referee_status.ICRA_buff_debuff_zone_status.F3_zone_status = pbuf[8];
								robot_referee_status.ICRA_buff_debuff_zone_status.F3_zone_buff_debuff_status = pbuf[8]>>1;
								robot_referee_status.ICRA_buff_debuff_zone_status.F4_zone_status = pbuf[8]>>4;
								robot_referee_status.ICRA_buff_debuff_zone_status.F4_zone_buff_debuff_status = pbuf[8]>>5;
								robot_referee_status.ICRA_buff_debuff_zone_status.F5_zone_status = pbuf[9];
								robot_referee_status.ICRA_buff_debuff_zone_status.F5_zone_buff_debuff_status = pbuf[9]>>1;
								robot_referee_status.ICRA_buff_debuff_zone_status.F6_zone_status = pbuf[9]>>4;
								robot_referee_status.ICRA_buff_debuff_zone_status.F6_zone_buff_debuff_status = pbuf[9]>>5;
								
								robot_referee_status.ICRA_buff_debuff_zone_status.red1_bullet_left = pbuf[11]*256+pbuf[10];
								robot_referee_status.ICRA_buff_debuff_zone_status.red2_bullet_left = pbuf[13]*256+pbuf[12];
								robot_referee_status.ICRA_buff_debuff_zone_status.blue1_bullet_left = pbuf[15]*256+pbuf[14];
								robot_referee_status.ICRA_buff_debuff_zone_status.blue2_bullet_left = pbuf[17]*256+pbuf[16];
							}
							else if(cmd==0x0101) //1Hz,场地事件数据
							{
								robot_referee_status.event_data.recv_cnt++;
								robot_referee_status.event_data.event_type = (pbuf[10]<<24)+(pbuf[9]<<16)+(pbuf[8]<<8)+pbuf[7];
							}
							else if(cmd==0x0102) //动作改变后发送,场地补给站动作标识数据
							{
								robot_referee_status.supply_projectile_action.recv_cnt++;
								robot_referee_status.supply_projectile_action.supply_projectile_id = pbuf[7];
								robot_referee_status.supply_projectile_action.supply_robot_id = pbuf[8];
								robot_referee_status.supply_projectile_action.supply_projectile_step = pbuf[9];
								robot_referee_status.supply_projectile_action.supply_projectile_num = pbuf[10];
							}
							else if(cmd==0x0104) //警告发生后发送,裁判警告信息
							{
								robot_referee_status.referee_warning.recv_cnt++;
								robot_referee_status.referee_warning.level = pbuf[7];
								robot_referee_status.referee_warning.foul_robot_id = pbuf[8];
							}
							else if(cmd==0x0105) //1Hz,飞镖发射口倒计时
							{
								robot_referee_status.dart_remaining_time.recv_cnt++;
								robot_referee_status.dart_remaining_time.dart_remaining_time = pbuf[7];
							}
							else //cmd error
							{
								robot_referee_status.cmd_error_count[5]++;
							}
						}
						else //check package_crc16 error
						{
							robot_referee_status.cmd_error_count[4]++;
							break;
						}
					}
					else //check package length error
					{
						robot_referee_status.cmd_error_count[3]++;
						break;
					}
				}
				else //check head_crc8 error
				{
					robot_referee_status.cmd_error_count[2]++;
					break;
				}
			}
			else //check frame_header & length error
			{
				robot_referee_status.cmd_error_count[1]++;
				break;
			}

			//
			remaining_n=remaining_n-(data_len+9);
			pbuf=pbuf+(data_len+9);
			
			if(remaining_n<=0){break;}
		}
		
		//
		fifo_head_pos=(fifo_head_pos+1)%REFEREE_FIFO_BUF_NUM;
		fifo_count--;
	}
}

/*---------------------DJI提供CRC校验代码---------------------*/
//crc8 generator polynomial:G(x)=x8+x5+x4+1
const uint8_t CRC8_INIT = 0xff;
const uint8_t CRC8_TAB[256] = { 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 
	0x20, 0xa3, 0xfd, 0x1f, 0x41, 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 
	0xbd, 0x3e, 0x60, 0x82, 0xdc, 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 
	0x03, 0x80, 0xde, 0x3c, 0x62, 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 
	0x9e, 0x1d, 0x43, 0xa1, 0xff, 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 
	0x66, 0xe5, 0xbb, 0x59, 0x07, 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 
	0xfb, 0x78, 0x26, 0xc4, 0x9a, 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 
	0x45, 0xc6, 0x98, 0x7a, 0x24, 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 
	0xd8, 0x5b, 0x05, 0xe7, 0xb9, 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 
	0xac, 0x2f, 0x71, 0x93, 0xcd, 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 
	0x31, 0xb2, 0xec, 0x0e, 0x50, 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 
	0x8f, 0x0c, 0x52, 0xb0, 0xee, 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 
	0x12, 0x91, 0xcf, 0x2d, 0x73, 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 
	0xea, 0x69, 0x37, 0xd5, 0x8b, 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 
	0x77, 0xf4, 0xaa, 0x48, 0x16, 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 
	0xc9, 0x4a, 0x14, 0xf6, 0xa8, 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 
	0x54, 0xd7, 0x89, 0x6b, 0x35};

/* 
** Descriptions: CRC8 checksum function 
** Input: Data to check,Stream length, initialized checksum 
** Output: CRC checksum 
*/
uint8_t Get_CRC8_Check_Sum(uint8_t *pchMessage, uint32_t dwLength, uint8_t ucCRC8)
{
	uint8_t ucIndex;
	while(dwLength--)
	{
		ucIndex=ucCRC8^(*pchMessage++);
		ucCRC8=CRC8_TAB[ucIndex];
	}
	return(ucCRC8); 
}

/*
** Descriptions: CRC8 Verify function 
** Input: Data to Verify,Stream length = Data + checksum
** Output: True or False (CRC Verify Result) 
*/
uint32_t Verify_CRC8_Check_Sum(uint8_t *pchMessage, uint32_t dwLength)
{
	uint8_t ucExpected;
	ucExpected=Get_CRC8_Check_Sum(pchMessage,dwLength-1,CRC8_INIT);
	return (ucExpected==pchMessage[dwLength-1]);
}

/* 
** Descriptions: append CRC8 to the end of data 
** Input: Data to CRC and append,Stream length = Data + checksum 
** Output: True or False (CRC Verify Result) 
*/
void Append_CRC8_Check_Sum(uint8_t *pchMessage, uint32_t dwLength)
{ 
	uint8_t ucCRC; 
	ucCRC=Get_CRC8_Check_Sum(pchMessage,dwLength-1,CRC8_INIT); 
	pchMessage[dwLength-1]=ucCRC; 
}

//crc16
const uint16_t CRC16_INIT = 0xffff;
const uint16_t CRC16_Table[256] = {0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 
	 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 
	 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 
	 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 
	 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 
	 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 
	 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 
	 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 
	 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 
	 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 
	 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 
	 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 
	 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 
	 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 
	 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 
	 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 
	 0x3de3, 0x2c6a, 0x1ef1, 0x0f78};

/* 
** Descriptions: CRC16 checksum function 
** Input: Data to check,Stream length, initialized checksum 
** Output: CRC checksum 
*/
uint16_t Get_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength, uint16_t wCRC) 
{
	uint8_t chData; 
	while(dwLength--)
	{ 
		chData=*pchMessage++; 
		wCRC=(wCRC>>8)^CRC16_Table[(wCRC^(uint16_t)(chData))&0x00ff]; 
	} 
	return wCRC; 
}

/*
** Descriptions: CRC16 Verify function 
** Input: Data to Verify,Stream length = Data + checksum
** Output: True or False (CRC Verify Result) 
*/ 
uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength) 
{ 
	uint16_t wExpected; 
	wExpected=Get_CRC16_Check_Sum(pchMessage,dwLength-2,CRC16_INIT);
	return ((wExpected&0x00ff)==pchMessage[dwLength-2]&&((wExpected>>8)&0x00ff)==pchMessage[dwLength-1]);
}

/* 
** Descriptions: append CRC16 to the end of data 
** Input: Data to CRC and append,Stream length = Data + checksum 
** Output: True or False (CRC Verify Result) 
*/ 
void Append_CRC16_Check_Sum(uint8_t * pchMessage,uint32_t dwLength) 
{ 
	uint16_t wCRC;
	wCRC = Get_CRC16_Check_Sum(pchMessage,dwLength-2,CRC16_INIT); 
	pchMessage[dwLength-2]=(wCRC&0x00ff); 
	pchMessage[dwLength-1]=((wCRC>>8)&0x00ff);
}

/*---------------------机器人间通信与客户端UI代码---------------------*/

/***********************************************************************
** 函 数 名： create_robot_interactive_package()
** 函数说明： 建立己方机器人间通信数据帧内容(未填充数据段)(暂时未用到)
**---------------------------------------------------------------------
** 输入参数： 数据帧缓冲区地址,数据帧缓冲区长度,数据段内容id,己方接收机器人id
** 返回参数： 无
***********************************************************************/
/*void create_robot_interactive_package(uint8_t* tx_buf, uint8_t tx_buf_len, uint16_t data_cmd_id, uint16_t receiver_robot_id)
{
	//4 bytes
	frame_header_t *p_frame_header = (frame_header_t *)(tx_buf+0);
	p_frame_header->sof=0xA5;
	p_frame_header->data_length=tx_buf_len-9; //数据长度
	p_frame_header->seq=student_interactive_seq++;
	
	//1 bytes
	Append_CRC8_Check_Sum(tx_buf, 5);
	
	//2 bytes
	uint16_t cmd_id = 0x0301; //交互数据指令
	memcpy(tx_buf+5, &cmd_id, sizeof(cmd_id));
	
	//6 bytes
	ext_student_interactive_header_data_t *p_student_interacitve_header = (ext_student_interactive_header_data_t *)(tx_buf+7);
	p_student_interacitve_header->data_cmd_id = data_cmd_id;
	p_student_interacitve_header->sender_ID = robot_referee_status.game_robot_status.robot_id;
	p_student_interacitve_header->receiver_ID = receiver_robot_id;
	
	//数据段(需提前填充好)
	
	//2 bytes  
	Append_CRC16_Check_Sum(tx_buf, tx_buf_len);
}*/

/***********************************************************************
** 函 数 名： create_ui_interactive_package()
** 函数说明： 建立机器人和客户端UI通信数据帧内容(未填充数据段)
**---------------------------------------------------------------------
** 输入参数： 数据帧缓冲区地址, 数据帧缓冲区长度, 数据段内容id
** 返回参数： 无
***********************************************************************/
void create_ui_interactive_package(uint8_t* tx_buf, uint8_t tx_buf_len, uint16_t data_cmd_id)
{
	//4 bytes
	frame_header_t *p_frame_header = (frame_header_t *)(tx_buf+0);
	p_frame_header->sof=0xA5;
	p_frame_header->data_length=tx_buf_len-9; //数据长度
	p_frame_header->seq=student_interactive_seq++;
	
	//1 bytes
	Append_CRC8_Check_Sum(tx_buf, 5);
	
	//2 bytes
	uint16_t cmd_id = 0x0301; //交互数据指令
	memcpy(tx_buf+5, &cmd_id, sizeof(cmd_id));
	
	//6 bytes
	ext_student_interactive_header_data_t *p_student_interacitve_header = (ext_student_interactive_header_data_t *)(tx_buf+7);
	p_student_interacitve_header->data_cmd_id = data_cmd_id;
	p_student_interacitve_header->sender_ID = robot_referee_status.game_robot_status.robot_id;
	p_student_interacitve_header->receiver_ID = (robot_referee_status.game_robot_status.robot_id + 0x0100);
	
	//数据段(需提前填充好)

	//2 bytes  
	Append_CRC16_Check_Sum(tx_buf, tx_buf_len);
}

/***********************************************************************
** 函 数 名： set_clear_graphics_data()
** 函数说明： 设置UI数据段内容:删除图形
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,操作,图层
** 返回参数： 无
***********************************************************************/
void set_clear_graphics_data(uint8_t* tx_buf, uint8_t operate, uint8_t layer)
{
	ext_client_custom_graphic_delete_t *p_client_custom_graphic_delete = (ext_client_custom_graphic_delete_t *)(tx_buf+0);
	
	p_client_custom_graphic_delete->operate_type=operate; //0-空操作;1-删除图层;2-删除所有
	p_client_custom_graphic_delete->layer=layer; //图层数0-9
}

/***********************************************************************
** 函 数 名： set_line_graphics_data()
** 函数说明： 设置UI数据段内容:直线数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,线宽,颜色,起点x,起点y,终点x,终点y
** 返回参数： 无
***********************************************************************/
void set_line_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_x, uint16_t start_y, uint16_t end_x, uint16_t end_y)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);
	
	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=0; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=0; //空
	p_graphic_data_struct->end_angle=0; //空
	p_graphic_data_struct->width=width; //线条宽度
	p_graphic_data_struct->start_x=start_x; //起点x坐标
	p_graphic_data_struct->start_y=start_y; //起点y坐标
	p_graphic_data_struct->graphic_config_3.value.radius=0; //空
	p_graphic_data_struct->graphic_config_3.value.end_x=end_x; //终点x坐标
	p_graphic_data_struct->graphic_config_3.value.end_y=end_y; //终点y坐标
}

/***********************************************************************
** 函 数 名： set_rectangle_graphics_data()
** 函数说明： 设置UI数据段内容:矩形数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,线宽,颜色,起点x,起点y,对角顶点x,对角顶点y
** 返回参数： 无
***********************************************************************/
void set_rectangle_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_x, uint16_t start_y, uint16_t opposite_x, uint16_t opposite_y)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);
	
	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=1; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=0; //空
	p_graphic_data_struct->end_angle=0; //空
	p_graphic_data_struct->width=width; //线条宽度
	p_graphic_data_struct->start_x=start_x; //起点x坐标
	p_graphic_data_struct->start_y=start_y; //起点y坐标
	p_graphic_data_struct->graphic_config_3.value.radius=0; //空
	p_graphic_data_struct->graphic_config_3.value.end_x=opposite_x; //对角顶点x坐标
	p_graphic_data_struct->graphic_config_3.value.end_y=opposite_y; //对角顶点y坐标
}

/***********************************************************************
** 函 数 名： set_circle_graphics_data()
** 函数说明： 设置UI数据段内容:整圆数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,线宽,颜色,圆心x,圆心y,半径
** 返回参数： 无
***********************************************************************/
void set_circle_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t center_x, uint16_t center_y, uint16_t radius)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);

	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=2; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=0; //空
	p_graphic_data_struct->end_angle=0; //空
	p_graphic_data_struct->width=width; //线条宽度
	p_graphic_data_struct->start_x=center_x; //圆心x坐标
	p_graphic_data_struct->start_y=center_y; //圆心y坐标
	p_graphic_data_struct->graphic_config_3.value.radius=radius; //半径
	p_graphic_data_struct->graphic_config_3.value.end_x=0; //空
	p_graphic_data_struct->graphic_config_3.value.end_y=0; //空
}

/***********************************************************************
** 函 数 名： set_ellipse_graphics_data()
** 函数说明： 设置UI数据段内容:椭圆数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,线宽,颜色,圆心x,圆心y,半轴x,半轴y
** 返回参数： 无
***********************************************************************/
void set_ellipse_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t center_x, uint16_t center_y, uint16_t half_axis_x, uint16_t half_axis_y)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);

	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=3; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=0; //空
	p_graphic_data_struct->end_angle=0; //空
	p_graphic_data_struct->width=width; //线条宽度
	p_graphic_data_struct->start_x=center_x; //圆心x坐标
	p_graphic_data_struct->start_y=center_y; //圆心y坐标
	p_graphic_data_struct->graphic_config_3.value.radius=0; //空
	p_graphic_data_struct->graphic_config_3.value.end_x=half_axis_x; //半轴x长度
	p_graphic_data_struct->graphic_config_3.value.end_y=half_axis_y; //半轴y长度
}

/***********************************************************************
** 函 数 名： set_arc_graphics_data()
** 函数说明： 设置UI数据段内容:圆弧数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,线宽,颜色,起始角度,终止角度,圆心x,圆心y,半轴x,半轴y
** 返回参数： 无
***********************************************************************/
void set_arc_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_angle, uint16_t end_angle, uint16_t center_x, uint16_t center_y, uint16_t half_axis_x, uint16_t half_axis_y)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);
	
	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=4; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=start_angle; //起始角度
	p_graphic_data_struct->end_angle=end_angle; //终止角度
	p_graphic_data_struct->width=width; //线条宽度
	p_graphic_data_struct->start_x=center_x; //圆心x坐标
	p_graphic_data_struct->start_y=center_y; //圆心y坐标
	p_graphic_data_struct->graphic_config_3.value.radius=0; //空
	p_graphic_data_struct->graphic_config_3.value.end_x=half_axis_x; //半轴x长度
	p_graphic_data_struct->graphic_config_3.value.end_y=half_axis_y; //半轴y长度
}

/***********************************************************************
** 函 数 名： set_integer_graphics_data()
** 函数说明： 设置UI数据段内容:整形数数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,字体大小,颜色,起点x,起点y,整数值
** 返回参数： 无
***********************************************************************/
void set_integer_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint8_t size, uint8_t color, uint16_t start_x, uint16_t start_y, int32_t value)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);

	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=5; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=size*10; //字体大小
	p_graphic_data_struct->end_angle=0; //空
	p_graphic_data_struct->width=size; //线条宽度
	p_graphic_data_struct->start_x=start_x; //起点x坐标
	p_graphic_data_struct->start_y=start_y; //起点y坐标
	p_graphic_data_struct->graphic_config_3.int32_value=value; //32位整型数
}

/***********************************************************************
** 函 数 名： set_float_graphics_data()
** 函数说明： 设置UI数据段内容:浮点数数据
**---------------------------------------------------------------------
** 输入参数： UI数据段缓冲区地址,图形名,操作,字体大小,颜色,起点x,起点y,浮点数值
** 返回参数： 无
***********************************************************************/
void set_float_graphics_data(uint8_t* tx_buf, char *name, uint8_t operate, uint8_t size, uint8_t color, uint16_t start_x, uint16_t start_y, float value)
{
	graphic_data_struct_t *p_graphic_data_struct = (graphic_data_struct_t *)(tx_buf+0);

	p_graphic_data_struct->graphic_name[0]=name[0];
	p_graphic_data_struct->graphic_name[1]=name[1];
	p_graphic_data_struct->graphic_name[2]=name[2];
	p_graphic_data_struct->operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_graphic_data_struct->graphic_tpye=6; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_graphic_data_struct->layer=0; //图层0-9
	p_graphic_data_struct->color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_graphic_data_struct->start_angle=size*10; //字体大小
	p_graphic_data_struct->end_angle=2; //小数位数
	p_graphic_data_struct->width=size; //线条宽度
	p_graphic_data_struct->start_x=start_x; //起点x坐标
	p_graphic_data_struct->start_y=start_y; //起点y坐标
	p_graphic_data_struct->graphic_config_3.int32_value=value*1000; //32位浮点数
}

/***********************************************************************
** 函 数 名： ClientUI_ClearLayer()
** 函数说明： 清除客户端所选图层的UI图形
**---------------------------------------------------------------------
** 输入参数： 图层
** 返回参数： 无
***********************************************************************/
void ClientUI_ClearLayer(uint8_t layer)
{
	uint8_t tx_buf[17]={0};
	
	set_clear_graphics_data(tx_buf+13, 1, layer);//删除所选图层
	create_ui_interactive_package(tx_buf, 17, 0x0100); //客户端删除图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 17, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawLine()
** 函数说明： 客户端UI画一个直线
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,线宽,颜色,起点x,起点y,终点x,终点y
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawLine(char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_x, uint16_t start_y, uint16_t end_x, uint16_t end_y)
{
	uint8_t tx_buf[30]={0};
	
	set_line_graphics_data(tx_buf+13, name, operate, width, color, start_x, start_y, end_x, end_y); //设置直线绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawRectangle()
** 函数说明： 客户端UI画一个矩形
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,线宽,颜色,起点x,起点y,对角顶点x,对角顶点y
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawRectangle(char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_x, uint16_t start_y, uint16_t opposite_x, uint16_t opposite_y)
{
	uint8_t tx_buf[30]={0};
	
	set_rectangle_graphics_data(tx_buf+13, name, operate, width, color, start_x, start_y, opposite_x, opposite_y); //设置矩形绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawCircle()
** 函数说明： 客户端UI画一个整圆
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,线宽,颜色,圆心x,圆心y,半径
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawCircle(char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t center_x, uint16_t center_y, uint16_t radius)
{
	uint8_t tx_buf[30]={0};
	
	set_circle_graphics_data(tx_buf+13, name, operate, width, color, center_x, center_y, radius); //设置整圆绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawEllipse()
** 函数说明： 客户端UI画一个椭圆
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,线宽,颜色,圆心x,圆心y,半轴x,半轴y
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawEllipse(char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t center_x, uint16_t center_y, uint16_t half_axis_x, uint16_t half_axis_y)
{
	uint8_t tx_buf[30]={0};
	
	set_ellipse_graphics_data(tx_buf+13, name, operate, width, color, center_x, center_y, half_axis_x, half_axis_y); //设置椭圆绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawArc()
** 函数说明： 客户端UI画一个圆弧
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,线宽,颜色,起始角度,终止角度,圆心x,圆心y,半轴x,半轴y
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawArc(char *name, uint8_t operate, uint16_t width, uint8_t color, uint16_t start_angle, uint16_t end_angle, uint16_t center_x, uint16_t center_y, uint16_t half_axis_x, uint16_t half_axis_y)
{
	uint8_t tx_buf[30]={0};
	
	set_arc_graphics_data(tx_buf+13, name, operate, width, color, start_angle, end_angle, center_x, center_y, half_axis_x, half_axis_y); //设置圆弧绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawInteger()
** 函数说明： 客户端UI画一个整数
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,字体大小,颜色,起点x,起点y,整数值
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawInteger(char *name, uint8_t operate, uint8_t size, uint8_t color, uint16_t start_x, uint16_t start_y, int32_t value)
{
	uint8_t tx_buf[30]={0};
	
	set_integer_graphics_data(tx_buf+13, name, operate, size, color, start_x, start_y, value); //设置整数绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawFloat()
** 函数说明： 客户端UI画一个浮点数
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,字体大小,颜色,起点x,起点y,浮点数值
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawFloat(char *name, uint8_t operate, uint8_t size, uint8_t color, uint16_t start_x, uint16_t start_y, float value)
{
	uint8_t tx_buf[30]={0};
	
	set_float_graphics_data(tx_buf+13, name, operate, size, color, start_x, start_y, value); //设置整数绘制数据
	create_ui_interactive_package(tx_buf, 30, 0x0101); //客户端绘制一个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 30, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_DrawString()
** 函数说明： 客户端UI画格式化字符串
**---------------------------------------------------------------------
** 输入参数： 图形名,操作,字体大小,颜色,起点x,起点y,格式化字符串
** 返回参数： 无
***********************************************************************/
void ClientUI_DrawString(char *name, uint8_t operate, uint8_t size, uint8_t color, uint16_t start_x, uint16_t start_y, const char *str, ...)
{
	uint8_t tx_buf[60]={0};
	uint8_t len=0;
	
	//4 bytes
	frame_header_t *p_frame_header = (frame_header_t *)(tx_buf+0);
	p_frame_header->sof=0xA5;
	p_frame_header->data_length=51; //数据长度
	p_frame_header->seq=student_interactive_seq++;
	
	//1 bytes
	Append_CRC8_Check_Sum(tx_buf, 5);
	
	//2 bytes
	uint16_t cmd_id = 0x0301;
	memcpy(tx_buf+5, &cmd_id, sizeof(cmd_id));
	
	//6 bytes
	ext_student_interactive_header_data_t *p_student_interacitve_header = (ext_student_interactive_header_data_t *)(tx_buf+7);
	p_student_interacitve_header->data_cmd_id = 0x0110; //客户端绘制字符图形
	p_student_interacitve_header->sender_ID = robot_referee_status.game_robot_status.robot_id;
	p_student_interacitve_header->receiver_ID = (robot_referee_status.game_robot_status.robot_id + 0x0100);
	
	//15+30 bytes
	ext_client_custom_character_t *p_client_custom_character =  (ext_client_custom_character_t *)(tx_buf+13);
	
  va_list ap;
	va_start(ap, str);
  len=vsprintf((char *)(p_client_custom_character->data), str, ap);
  va_end(ap);
	
	p_client_custom_character->grapic_data_struct.graphic_name[0]=name[0];
	p_client_custom_character->grapic_data_struct.graphic_name[1]=name[1];
	p_client_custom_character->grapic_data_struct.graphic_name[2]=name[2];
	p_client_custom_character->grapic_data_struct.operate_tpye=operate; //0-空;1-增加;2-修改;3-删除
	p_client_custom_character->grapic_data_struct.graphic_tpye=7; //0-直线;1-矩形;2-整圆;3-椭圆;4-圆弧;5-整形数;6-浮点数;7-字符
	p_client_custom_character->grapic_data_struct.layer=0; //图层0-9
	p_client_custom_character->grapic_data_struct.color=color; //0-红蓝主色;1-黄色;2-绿色;3-橙色;4-紫红色;5-粉色;6-青色;7-黑色;8-白色
	p_client_custom_character->grapic_data_struct.start_angle=size*10; //字体大小
	p_client_custom_character->grapic_data_struct.end_angle=len; //字符长度
	p_client_custom_character->grapic_data_struct.width=size; //线条宽度
	p_client_custom_character->grapic_data_struct.start_x=start_x; //起点x坐标
	p_client_custom_character->grapic_data_struct.start_y=start_y; //起点y坐标
	p_client_custom_character->grapic_data_struct.graphic_config_3.value.radius=0; //空
	p_client_custom_character->grapic_data_struct.graphic_config_3.value.end_x=0; //空
	p_client_custom_character->grapic_data_struct.graphic_config_3.value.end_y=0; //空

	//2 bytes
	Append_CRC16_Check_Sum(tx_buf, 60);
	
	//
	HAL_UART_Transmit(&huart1, tx_buf, 60, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_Update7Graphcis_1()
** 函数说明： 专用功能,客户端UI绘制七个图形:机器人工作模式(7个)
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void ClientUI_Update7Graphcis_1(void)
{
	uint8_t tx_buf[120]={0};
	
	//运动模式
	if(client_ui_status.movement_mode==0) //MOTOR_DISABLE
	{
		set_line_graphics_data(tx_buf+13,"M1A",UI_OPERATE_UPDATE,30,UI_COLOR_VIOLETRED,150,845,150+30,845);
		set_line_graphics_data(tx_buf+28,"M1B",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,188,845,188,845);
		set_line_graphics_data(tx_buf+43,"M1C",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,226,845,226,845);
	}
	else if(client_ui_status.movement_mode==1) //CHASSIS_FOLLOW_GIMBAL
	{
		set_line_graphics_data(tx_buf+13,"M1A",UI_OPERATE_UPDATE,30,UI_COLOR_VIOLETRED,150,845,150,845);
		if(client_ui_status.chassis_lock_mode==1){set_line_graphics_data(tx_buf+28,"M1B",UI_OPERATE_UPDATE,30,UI_COLOR_PINK,188,845,188+30,845);} //底盘旋转锁定
		else if(client_ui_status.corner_face_enemy_mode==1){set_line_graphics_data(tx_buf+28,"M1B",UI_OPERATE_UPDATE,30,UI_COLOR_ORANGE,188,845,188+30,845);} //45度对敌
		else{set_line_graphics_data(tx_buf+28,"M1B",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,188,845,188+30,845);}
		set_line_graphics_data(tx_buf+43,"M1C",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,226,845,226,845);
	}
	else if(client_ui_status.movement_mode==2) //CHASSIS_GYRO_ROTATION
	{
		set_line_graphics_data(tx_buf+13,"M1A",UI_OPERATE_UPDATE,30,UI_COLOR_VIOLETRED,150,845,150,845);
		set_line_graphics_data(tx_buf+28,"M1B",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,188,845,188,845);
		set_line_graphics_data(tx_buf+43,"M1C",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,226,845,226+30,845);
	}
	
	//底盘加速模式
	if(client_ui_status.chassis_accelerate_mode==1){set_line_graphics_data(tx_buf+58,"M1D",UI_OPERATE_UPDATE,30,UI_COLOR_ORANGE,268,845,268+30,845);}
	else{set_line_graphics_data(tx_buf+58,"M1D",UI_OPERATE_UPDATE,30,UI_COLOR_ORANGE,268,845,268,845);}
	
	//云台慢速模式
	if(client_ui_status.gimbal_slow_mode==1){set_line_graphics_data(tx_buf+73,"M1E",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,306,845,306+30,845);}
	else{set_line_graphics_data(tx_buf+73,"M1E",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,306,845,306,845);}
	
	//枪管热量限制模式
	if(client_ui_status.ignore_shoot_heat_limit_mode==1){set_line_graphics_data(tx_buf+88,"M1F",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,344,845,344,845);}
	else{set_line_graphics_data(tx_buf+88,"M1F",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,344,845,344+30,845);}
	
	//云台自瞄控制模式
	if(client_ui_status.gimbal_autoaiming_control_mode==1){set_line_graphics_data(tx_buf+103,"M1G",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,386,845,386+30,845);}
	else{set_line_graphics_data(tx_buf+103,"M1G",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,386,845,386,845);}
	
	create_ui_interactive_package(tx_buf, 120, 0x0104); //客户端绘制七个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 120, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_Update7Graphcis_2()
** 函数说明： 专用功能,客户端UI绘制七个图形:自检状态(1个)、弹舱盖开合(1个)、超级电容能量弧线(1个)、动态边框线(4个)
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void ClientUI_Update7Graphcis_2(void)
{
	uint8_t tx_buf[120]={0};
	
	if(client_ui_status.self_check_state==0){set_line_graphics_data(tx_buf+13,"M2A",UI_OPERATE_UPDATE,30,UI_COLOR_GREEN,150,785,180,785);}
	else if(client_ui_status.self_check_state==1){set_line_graphics_data(tx_buf+13,"M2A",UI_OPERATE_UPDATE,30,UI_COLOR_YELLOW,150,785,180,785);}
	else if(client_ui_status.self_check_state==2){set_line_graphics_data(tx_buf+13,"M2A",UI_OPERATE_UPDATE,30,UI_COLOR_VIOLETRED,150,785,180,785);}
	if(client_ui_status.bulletroom_open_flag==1){set_line_graphics_data(tx_buf+28,"M3A",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,150,725,150+30,725);} //BLUEGREE-开盖
	else{set_line_graphics_data(tx_buf+28,"M3A",UI_OPERATE_UPDATE,30,UI_COLOR_BLUEGREEN,150,725,150,725);} //透明-合盖
	set_arc_graphics_data(tx_buf+43,"C04",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,0,360*client_ui_status.supercap_energy_percent/100,700,520,70,40); //超级电容弧线
	//set_line_graphics_data(tx_buf+58,);
	//set_line_graphics_data(tx_buf+73,);
	//set_rectangle_graphics_data(tx_buf+88,);
	//set_rectangle_graphics_data(tx_buf+103,);
	
	create_ui_interactive_package(tx_buf, 120, 0x0104); //客户端绘制七个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 120, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： ClientUI_Update7Graphcis_3()
** 函数说明： 专用功能,客户端UI绘制七个图形:底盘移动速度(1个)、小陀螺转速(1个)、摩擦轮转速(2个)、拨弹射频(1个)、底盘动态中心线(1个)、自瞄识别稳定率(1个)
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void ClientUI_Update7Graphcis_3(void)
{
	uint8_t tx_buf[120]={0};
	
	set_line_graphics_data(tx_buf+13,"S1X",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,1700,710,1720+200*client_ui_status.chassis_move_speed,710);
	set_line_graphics_data(tx_buf+28,"S2X",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,1700,610,1720+200*client_ui_status.gyro_rotate_speed,610);
	set_line_graphics_data(tx_buf+43,"S3X",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,1700,510,1720+200*client_ui_status.shoot_motor_speed[0],510);
	set_line_graphics_data(tx_buf+58,"S3Y",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,1700,500,1720+200*client_ui_status.shoot_motor_speed[1],500);
	set_line_graphics_data(tx_buf+73,"S4X",UI_OPERATE_UPDATE,5,UI_COLOR_VIOLETRED,1720,410,1720+200*client_ui_status.turnbullet_frequency/20,410);
	set_line_graphics_data(tx_buf+88,"L41",UI_OPERATE_UPDATE,10,UI_COLOR_YELLOW,960+client_ui_status.yaw_delt_angle*2,120,960+client_ui_status.yaw_delt_angle*2,180);
	set_line_graphics_data(tx_buf+103,"V13",UI_OPERATE_UPDATE,28,UI_COLOR_BLUEGREEN,850,50,850+300*client_ui_status.auto_aiming_stability,50);
	create_ui_interactive_package(tx_buf, 120, 0x0104); //客户端绘制七个图形
	
	HAL_UART_Transmit(&huart1, tx_buf, 120, 100); //发送数据帧
}

/***********************************************************************
** 函 数 名： RefreshStaticClientUI_FAST()
** 函数说明： 刷新(新建)静态客户端UI界面
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void RefreshStaticClientUI_Fast(void)
{
	//客户端屏幕尺寸为1920*1080, 左下角为(0,0), 中心点为(960,540), 点坐标(x,y)中 x为水平 y为竖直
	//
	ClientUI_ClearLayer(0); HAL_Delay(50); //清除图层0
	ClientUI_ClearLayer(0); HAL_Delay(50);
	
	//
	ClientUI_DrawString("X01",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1700,850,"FAST"); HAL_Delay(10);
	
	//动态车边框线
	ClientUI_DrawLine("L31",UI_OPERATE_ADD,5,UI_COLOR_YELLOW,700,150,900,150); HAL_Delay(10); //
	ClientUI_DrawLine("L32",UI_OPERATE_ADD,5,UI_COLOR_YELLOW,1020,150,1220,150); HAL_Delay(10); //
	ClientUI_DrawLine("L33",UI_OPERATE_ADD,5,UI_COLOR_YELLOW,400,10,700,150); HAL_Delay(10); //
	ClientUI_DrawLine("L34",UI_OPERATE_ADD,5,UI_COLOR_YELLOW,1220,150,1520,10); HAL_Delay(10); //
	
	//底盘动态中心线
	ClientUI_DrawLine("L41",UI_OPERATE_ADD,10,UI_COLOR_YELLOW,960,120,960,180); HAL_Delay(10); //
}

/***********************************************************************
** 函 数 名： RefreshStaticClientUI_Normal()
** 函数说明： 刷新(新建)静态客户端UI界面
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void RefreshStaticClientUI_Normal(void)
{
	//客户端屏幕尺寸为1920*1080, 左下角为(0,0), 中心点为(960,540), 点坐标(x,y)中 x为水平 y为竖直
	//
	ClientUI_ClearLayer(0); HAL_Delay(50); //清除图层0
	ClientUI_ClearLayer(0); HAL_Delay(50);
	
	//
	ClientUI_DrawString("X02",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1700,850,"NORMAL"); HAL_Delay(10);
	
	//测试用
	//ClientUI_DrawLine("TS1",UI_OPERATE_ADD,1,UI_COLOR_RED_BLUE,700,700,1200,700); HAL_Delay(20); //直线
	//ClientUI_DrawRectangle("TS2",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,650,600,850,500); HAL_Delay(20); //矩形
	//ClientUI_DrawCircle("TS3",UI_OPERATE_ADD,3,UI_COLOR_GREEN,1150,550,50); HAL_Delay(20); //正圆
	//ClientUI_DrawEllipse("TS4",UI_OPERATE_ADD,4,UI_COLOR_ORANGE,850,350,100,50); HAL_Delay(20); //椭圆
	//ClientUI_DrawArc("TS5",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,30,270,1100,350,60,50); HAL_Delay(20); //弧线
	//ClientUI_DrawInteger("TS6",UI_OPERATE_ADD,2,UI_COLOR_BLUEGREEN,750,200,12345); HAL_Delay(20); //整数
	//ClientUI_DrawFloat("TS7",UI_OPERATE_ADD,2,UI_COLOR_PINK,950,200,123.45); HAL_Delay(20); //浮点
	//ClientUI_DrawString("TS8",UI_OPERATE_ADD,2,UI_COLOR_BLACK,750,150,"HAHA"); HAL_Delay(20); //普通字符串
	//ClientUI_DrawString("TS9",UI_OPERATE_ADD,2,UI_COLOR_WHITE,950,150,"TMP=%.2f",123.45f); HAL_Delay(20); //格式化字符串

	//瞄准刻度线
	//竖直线
	ClientUI_DrawLine("L01",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,960,290,960,510); HAL_Delay(10);
	ClientUI_DrawLine("L03",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,961,290,961,510); HAL_Delay(10);
	ClientUI_DrawLine("L02",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,960,570,960,630); HAL_Delay(10);
	ClientUI_DrawLine("L04",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,961,570,961,630); HAL_Delay(10);
	//下部水平线
	ClientUI_DrawLine("L11",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,290,970,290); HAL_Delay(10);
	ClientUI_DrawLine("L12",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,300,970,300); HAL_Delay(10);
	ClientUI_DrawLine("L13",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,310,970,310); HAL_Delay(10);
	ClientUI_DrawLine("L14",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,930,320,990,320); HAL_Delay(10);
	ClientUI_DrawLine("L15",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,330,970,330); HAL_Delay(10);
	ClientUI_DrawLine("L16",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,340,970,340); HAL_Delay(10);
	ClientUI_DrawLine("L17",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,350,970,350); HAL_Delay(10);
	ClientUI_DrawLine("L18",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,930,360,990,360); HAL_Delay(10);
	ClientUI_DrawLine("L19",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,370,970,370); HAL_Delay(10);
	ClientUI_DrawLine("L1A",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,380,970,380); HAL_Delay(10);
	ClientUI_DrawLine("L1B",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,390,970,390); HAL_Delay(10);
	ClientUI_DrawLine("L1C",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,930,400,990,400); HAL_Delay(10);
	ClientUI_DrawLine("L1D",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,410,970,410); HAL_Delay(10);
	ClientUI_DrawLine("L1E",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,420,970,420); HAL_Delay(10);
	ClientUI_DrawLine("L1F",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,430,970,430); HAL_Delay(10);
	ClientUI_DrawLine("L1G",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,930,440,990,440); HAL_Delay(10);
	ClientUI_DrawLine("L1H",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,450,970,450); HAL_Delay(10);
	ClientUI_DrawLine("L1I",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,460,970,460); HAL_Delay(10);
	ClientUI_DrawLine("L1J",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,470,970,470); HAL_Delay(10);
	ClientUI_DrawLine("L1K",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,930,480,990,480); HAL_Delay(10);
	ClientUI_DrawLine("L1L",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,490,970,490); HAL_Delay(10);
	ClientUI_DrawLine("L1M",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,500,970,500); HAL_Delay(10);
	ClientUI_DrawLine("L1N",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,510,970,510); HAL_Delay(10);
	//上部水平线
	ClientUI_DrawLine("L21",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,570,970,570); HAL_Delay(10);
	ClientUI_DrawLine("L22",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,580,970,580); HAL_Delay(10);
	ClientUI_DrawLine("L23",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,590,970,590); HAL_Delay(10);
	ClientUI_DrawLine("L24",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,600,970,600); HAL_Delay(10);
	ClientUI_DrawLine("L25",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,610,970,610); HAL_Delay(10);
	ClientUI_DrawLine("L26",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,620,970,620); HAL_Delay(10);
	ClientUI_DrawLine("L27",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,950,630,970,630); HAL_Delay(10);

//UI设置
	
	//云台俯仰角度
	ClientUI_DrawString("G01",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1200,600,"PITCH"); HAL_Delay(10);
	ClientUI_DrawString("G02",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1185,550,"-00.00"); HAL_Delay(10); //
	
	//超级电容电压
	ClientUI_DrawString("C01",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,635,600,"CAPVOLT"); HAL_Delay(10);
	ClientUI_DrawString("C02",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,655,530,"00.0V"); HAL_Delay(10); //
	ClientUI_DrawEllipse("C03",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,700,520,70,40); HAL_Delay(10);
	ClientUI_DrawArc("C04",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,0,330,700,520,70,40); HAL_Delay(10); //
	
	//机器人模式
	ClientUI_DrawString("M11",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,30,855," MODE:"); HAL_Delay(10);
	ClientUI_DrawRectangle("M12",UI_OPERATE_ADD,3,UI_COLOR_WHITE,148,862,182,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M13",UI_OPERATE_ADD,3,UI_COLOR_WHITE,186,862,220,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M14",UI_OPERATE_ADD,3,UI_COLOR_WHITE,224,862,258,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M15",UI_OPERATE_ADD,3,UI_COLOR_WHITE,266,862,300,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M16",UI_OPERATE_ADD,3,UI_COLOR_WHITE,304,862,338,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M17",UI_OPERATE_ADD,3,UI_COLOR_WHITE,342,862,376,828); HAL_Delay(10);
	ClientUI_DrawRectangle("M18",UI_OPERATE_ADD,3,UI_COLOR_WHITE,384,862,418,828); HAL_Delay(10);
	ClientUI_DrawLine("M1A",UI_OPERATE_ADD,30,UI_COLOR_VIOLETRED,150,845,180,845); HAL_Delay(10); //VIOLETRED->MOTOR_DISABLE
	ClientUI_DrawLine("M1B",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,188,845,218,845); HAL_Delay(10); //BLUEGREEN->CHASSIS_FOLLOW_GIMBAL;PINK->CHASSIS_LOCK;ORANGE->CORNER_TO_ENEMY
	ClientUI_DrawLine("M1C",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,226,845,256,845); HAL_Delay(10); //BLUEGREEN->CHASSIS_GYRO_ROTATION
	ClientUI_DrawLine("M1D",UI_OPERATE_ADD,30,UI_COLOR_ORANGE,268,845,298,845); HAL_Delay(10); 		//ORANGE->CHASSIS_ACCELERATE
	ClientUI_DrawLine("M1E",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,306,845,336,845); HAL_Delay(10); //BLUEGREEN->GIMAL_SLOW_FOR_AIMING
	ClientUI_DrawLine("M1F",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,344,845,374,845); HAL_Delay(10); //BLUEGREEN->IGNORE_SHOOT_HEAT_LIMIT
	ClientUI_DrawLine("M1G",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,386,845,416,845); HAL_Delay(10); //BLUEGREEN->GIMAL_AUTO_AIMING_CONTROL

	//自检状态
	ClientUI_DrawString("M21",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,30,795,"STATE:"); HAL_Delay(10);
	ClientUI_DrawRectangle("M22",UI_OPERATE_ADD,3,UI_COLOR_WHITE,148,802,182,768); HAL_Delay(10);
	ClientUI_DrawLine("M2A",UI_OPERATE_ADD,30,UI_COLOR_GREEN,150,785,180,785); HAL_Delay(10); //GREEN-正常; YELLOW-告警; VIOLETRED-异常
	
	//弹舱盖开合
	ClientUI_DrawString("M31",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,30,735,"COVER:"); HAL_Delay(10);
	ClientUI_DrawRectangle("M32",UI_OPERATE_ADD,3,UI_COLOR_WHITE,148,742,182,708); HAL_Delay(10);
	ClientUI_DrawLine("M3A",UI_OPERATE_ADD,30,UI_COLOR_BLUEGREEN,150,725,180,725); HAL_Delay(10); //BLUEGREEN-开盖; 透明-合盖
	
	//底盘移动速度
	ClientUI_DrawString("S11",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1840,750,"MOVE"); HAL_Delay(10);
	ClientUI_DrawLine("S12",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,1700,710,1920,710); HAL_Delay(10);
	ClientUI_DrawLine("S13",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1720,710,1720,700); HAL_Delay(10);
	ClientUI_DrawLine("S14",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1770,710,1770,700); HAL_Delay(10);
	ClientUI_DrawLine("S15",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1820,710,1820,700); HAL_Delay(10);
	ClientUI_DrawLine("S16",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1870,710,1870,700); HAL_Delay(10);
	ClientUI_DrawLine("S17",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1919,710,1919,700); HAL_Delay(10);
	ClientUI_DrawLine("S1X",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,1700,710,1720,710); HAL_Delay(10); //
	
	//小陀螺转速
	ClientUI_DrawString("S21",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1800,650,"ROTATE"); HAL_Delay(10);
	ClientUI_DrawLine("S22",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,1700,610,1920,610); HAL_Delay(10);
	ClientUI_DrawLine("S23",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1720,610,1720,600); HAL_Delay(10);
	ClientUI_DrawLine("S24",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1770,610,1770,600); HAL_Delay(10);
	ClientUI_DrawLine("S25",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1820,610,1820,600); HAL_Delay(10);
	ClientUI_DrawLine("S26",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1870,610,1870,600); HAL_Delay(10);
	ClientUI_DrawLine("S27",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1919,610,1919,600); HAL_Delay(10);
	ClientUI_DrawLine("S2X",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,1700,610,1720,610); HAL_Delay(10); //
	
	//摩擦轮转速
	ClientUI_DrawString("S31",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1820,550,"SHOOT"); HAL_Delay(10);
	ClientUI_DrawLine("S32",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,1700,510,1920,510); HAL_Delay(10);
	ClientUI_DrawLine("S33",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,1700,500,1920,500); HAL_Delay(10);
	ClientUI_DrawLine("S34",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1720,510,1720,490); HAL_Delay(10);
	ClientUI_DrawLine("S35",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1770,510,1770,490); HAL_Delay(10);
	ClientUI_DrawLine("S36",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1820,510,1820,490); HAL_Delay(10);
	ClientUI_DrawLine("S37",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1870,510,1870,490); HAL_Delay(10);
	ClientUI_DrawLine("S38",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1919,510,1919,490); HAL_Delay(10);
	ClientUI_DrawLine("S3X",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,1700,510,1720,510); HAL_Delay(10); //
	ClientUI_DrawLine("S3Y",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,1700,500,1720,500); HAL_Delay(10); //
	
	//拨弹频率
	ClientUI_DrawString("S41",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1840,450,"FREQ"); HAL_Delay(10);
	ClientUI_DrawLine("S42",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,1700,410,1920,410); HAL_Delay(10);
	ClientUI_DrawLine("S43",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1720,410,1720,400); HAL_Delay(10);
	ClientUI_DrawLine("S44",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1770,410,1770,400); HAL_Delay(10);
	ClientUI_DrawLine("S45",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1820,410,1820,400); HAL_Delay(10);
	ClientUI_DrawLine("S46",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1870,410,1870,400); HAL_Delay(10);
	ClientUI_DrawLine("S47",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1919,410,1919,400); HAL_Delay(10);
	ClientUI_DrawLine("S4X",UI_OPERATE_ADD,5,UI_COLOR_VIOLETRED,1720,410,1720,410); HAL_Delay(10); //
	
	//自瞄识别稳定率
	ClientUI_DrawLine("V11",UI_OPERATE_ADD,32,UI_COLOR_WHITE,800,50,1152,50); HAL_Delay(10);
	ClientUI_DrawRectangle("V12",UI_OPERATE_ADD,2,UI_COLOR_BLACK,849,65,1151,35); HAL_Delay(10);
	ClientUI_DrawLine("V13",UI_OPERATE_ADD,28,UI_COLOR_BLUEGREEN,850,50,850,50); HAL_Delay(10); //

	//自瞄识别数字
	//ClientUI_DrawString("V21",UI_OPERATE_ADD,2,UI_COLOR_BLACK,820,60,"0"); HAL_Delay(10); //
	

}

/***********************************************************************
** 函 数 名： RefreshStaticClientUI_Debug()
** 函数说明： 刷新(新建)静态客户端UI界面
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void RefreshStaticClientUI_Debug(void)
{
	//客户端屏幕尺寸为1920*1080, 左下角为(0,0), 中心点为(960,540), 点坐标(x,y)中 x为水平 y为竖直
	//
	ClientUI_ClearLayer(0); HAL_Delay(50); //清除图层0
	ClientUI_ClearLayer(0); HAL_Delay(50);

	//
	ClientUI_DrawString("X04",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1700,850,"DEBUG"); HAL_Delay(10);
	
	//机器人详细调试信息
	ClientUI_DrawString("D01",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,800,"ROBOT_ID: 0"); HAL_Delay(10);
	ClientUI_DrawString("D02",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,780,"CHASSIS_POWER: 0 W"); HAL_Delay(10);
	ClientUI_DrawString("D03",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,760,"SHOOT_LIMIT: 0 M/S"); HAL_Delay(10);
	ClientUI_DrawString("D04",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,740,"HEAT_LIMIT: 0"); HAL_Delay(10);
	ClientUI_DrawString("D05",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,720,"COOLING_RATE: 0"); HAL_Delay(10);
	ClientUI_DrawString("D06",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,680,"AUTO_AIMING_FPS: 0.0"); HAL_Delay(10);
	ClientUI_DrawString("D07",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,680,"BAT_VOLTAGE: 0.00V"); HAL_Delay(10);
	ClientUI_DrawString("D08",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,640,"TEMP_BMI088: 0"); HAL_Delay(10);
	ClientUI_DrawString("D09",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,620,"TEMP_CHIP: 0"); HAL_Delay(10);
	ClientUI_DrawString("D10",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,600,"TEMP_CHASSIS1: 0"); HAL_Delay(10);
	ClientUI_DrawString("D11",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,580,"TEMP_CHASSIS2: 0"); HAL_Delay(10);
	ClientUI_DrawString("D12",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,560,"TEMP_CHASSIS3: 0"); HAL_Delay(10);
	ClientUI_DrawString("D13",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,20,540,"TEMP_CHASSIS4: 0"); HAL_Delay(10);
	ClientUI_DrawString("D14",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,640,"TEMP_GMIBAL_YAW:   0"); HAL_Delay(10);
	ClientUI_DrawString("D15",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,620,"TEMP_GMIBAL_PITCH: 0"); HAL_Delay(10);
	ClientUI_DrawString("D16",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,580,"TEMP_SHOOTER1: 0"); HAL_Delay(10);
	ClientUI_DrawString("D17",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,560,"TEMP_SHOOTER2: 0"); HAL_Delay(10);
	ClientUI_DrawString("D18",UI_OPERATE_ADD,1,UI_COLOR_YELLOW,270,540,"TEMP_TURNBULLET:  0"); HAL_Delay(10);
	
}

/***********************************************************************
** 函 数 名： RefreshStaticClientUI_Energy()
** 函数说明： 刷新(新建)静态客户端UI界面
**---------------------------------------------------------------------
** 输入参数： 无
** 返回参数： 无
***********************************************************************/
void RefreshStaticClientUI_Energy(void)
{
	//客户端屏幕尺寸为1920*1080, 左下角为(0,0), 中心点为(960,540), 点坐标(x,y)中 x为水平 y为竖直
	//
	ClientUI_ClearLayer(0); HAL_Delay(50); //清除图层0
	ClientUI_ClearLayer(0); HAL_Delay(50);
	
	//
	ClientUI_DrawString("X08",UI_OPERATE_ADD,2,UI_COLOR_YELLOW,1700,850,"ENERGY"); HAL_Delay(10);
	
	//
	
	
	
	
	
	
}

/***********************************************************************
** 函 数 名： RefreshDynamicClientUI()
** 函数说明： 刷新(更新)动态客户端UI界面
**---------------------------------------------------------------------
** 输入参数： 详细调试信息显示控制标志位
** 返回参数： 无
***********************************************************************/
void RefreshDynamicClientUI_Normal()
{
	//刷新云台角度值(1个) 60Bytes
	ClientUI_DrawString("G02",UI_OPERATE_UPDATE,2,UI_COLOR_YELLOW,1185,550,"%.2f", client_ui_status.pitch_angle); HAL_Delay(15);
	
	//刷新超级电容电压值(1个) 60Bytes 
	ClientUI_DrawString("C02",UI_OPERATE_UPDATE,2,UI_COLOR_YELLOW,655,530,"%.2f", client_ui_status.supercap_voltage); HAL_Delay(15);
	
	//刷新机器人工作模式(7个) 120Bytes
	ClientUI_Update7Graphcis_1(); HAL_Delay(15);
	
	//刷新自检状态(1个)、弹舱盖开合(1个)、超级电容能量弧线(1个)、底盘动态边框线(4个) 120Bytes
	ClientUI_Update7Graphcis_2(); HAL_Delay(15);
	
	//刷新底盘移动速度(1个)、小陀螺转速(1个)、摩擦轮转速(2个)、拨弹射频(1个)、底盘动态中心线(1个)、自瞄识别稳定率(1个) 120Bytes
	ClientUI_Update7Graphcis_3(); HAL_Delay(15);
	
	//刷新自瞄识别数字(1个) 60Bytes
	ClientUI_DrawString("V21",UI_OPERATE_UPDATE,2,UI_COLOR_BLACK,820,60,"%d", client_ui_status.auto_aiming_num); HAL_Delay(15);
	
	//刷新调试参数显示
	/*if(*ui_show_flag==1)
	{
		ClientUI_DrawString("D01",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,800,"ROBOT_ID: %d",client_ui_status.robot_id); HAL_Delay(15);
		ClientUI_DrawString("D02",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,780,"CHASSIS_POWER: %d W",client_ui_status.max_chassis_power); HAL_Delay(15);
		ClientUI_DrawString("D03",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,760,"SHOOT_LIMIT: %d M/S",client_ui_status.shoot_speed_limit); HAL_Delay(15);
		ClientUI_DrawString("D04",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,740,"HEAT_LIMIT: %d",client_ui_status.shoot_heat_limit); HAL_Delay(15);
		ClientUI_DrawString("D05",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,720,"COOLING_RATE: %d",client_ui_status.shoot_cooling_rate); HAL_Delay(15);
		ClientUI_DrawString("D06",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,680,"AUTO_AIMING_FPS: %.2f",client_ui_status.auto_aiming_capture_fps); HAL_Delay(15);
		ClientUI_DrawString("D07",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,680,"BAT_VOLTAGE: %.2fV",client_ui_status.battery_voltage); HAL_Delay(15);
		ClientUI_DrawString("D08",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,640,"TEMP_BMI088: %.2f",client_ui_status.bmi088_temperature); HAL_Delay(15);
		ClientUI_DrawString("D09",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,620,"TEMP_CHIP: %.2f",client_ui_status.chip_temperature); HAL_Delay(15);
		ClientUI_DrawString("D10",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,600,"TEMP_CHASSIS1: %d",client_ui_status.motor_temperature[0]); HAL_Delay(15);
		ClientUI_DrawString("D11",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,580,"TEMP_CHASSIS2: %d",client_ui_status.motor_temperature[1]); HAL_Delay(15);
		ClientUI_DrawString("D12",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,560,"TEMP_CHASSIS3: %d",client_ui_status.motor_temperature[2]); HAL_Delay(15);
		ClientUI_DrawString("D13",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,540,"TEMP_CHASSIS4: %d",client_ui_status.motor_temperature[3]); HAL_Delay(15);
		ClientUI_DrawString("D14",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,640,"TEMP_GMIBAL_YAW: %d",client_ui_status.motor_temperature[4]); HAL_Delay(15);
		ClientUI_DrawString("D15",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,620,"TEMP_GMIBAL_PITCH: %d",client_ui_status.motor_temperature[5]); HAL_Delay(15);
		ClientUI_DrawString("D16",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,580,"TEMP_SHOOTER1: %d",client_ui_status.motor_temperature[6]); HAL_Delay(15);
		ClientUI_DrawString("D17",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,560,"TEMP_SHOOTER2: %d",client_ui_status.motor_temperature[7]); HAL_Delay(15);
		ClientUI_DrawString("D18",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,540,"TEMP_TURNBULLET:  %d",client_ui_status.motor_temperature[8]); HAL_Delay(15);
		*ui_show_flag=0;
	}
	//关闭调试参数显示
	else if(*ui_show_flag==10)
	{
		ClientUI_DrawString("D01",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,800,""); HAL_Delay(15);
		ClientUI_DrawString("D02",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,780,""); HAL_Delay(15);
		ClientUI_DrawString("D03",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,760,""); HAL_Delay(15);
		ClientUI_DrawString("D04",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,740,""); HAL_Delay(15);
		ClientUI_DrawString("D05",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,720,""); HAL_Delay(15);
		ClientUI_DrawString("D06",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,680,""); HAL_Delay(15);
		ClientUI_DrawString("D07",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,680,""); HAL_Delay(15);
		ClientUI_DrawString("D08",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,640,""); HAL_Delay(15);
		ClientUI_DrawString("D09",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,620,""); HAL_Delay(15);
		ClientUI_DrawString("D10",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,600,""); HAL_Delay(15);
		ClientUI_DrawString("D11",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,580,""); HAL_Delay(15);
		ClientUI_DrawString("D12",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,560,""); HAL_Delay(15);
		ClientUI_DrawString("D13",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,540,""); HAL_Delay(15);
		ClientUI_DrawString("D14",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,640,""); HAL_Delay(15);
		ClientUI_DrawString("D15",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,620,""); HAL_Delay(15);
		ClientUI_DrawString("D16",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,580,""); HAL_Delay(15);
		ClientUI_DrawString("D17",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,560,""); HAL_Delay(15);
		ClientUI_DrawString("D18",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,540,""); HAL_Delay(15);
		*ui_show_flag=0;
	}*/
}

void RefreshDynamicClientUI_Fast()
{

}

void RefreshDynamicClientUI_Debug()
{
		ClientUI_DrawString("D01",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,800,"ROBOT_ID: %d",client_ui_status.robot_id); HAL_Delay(15);
		ClientUI_DrawString("D02",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,780,"CHASSIS_POWER: %d W",client_ui_status.max_chassis_power); HAL_Delay(15);
		ClientUI_DrawString("D03",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,760,"SHOOT_LIMIT: %d M/S",client_ui_status.shoot_speed_limit); HAL_Delay(15);
		ClientUI_DrawString("D04",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,740,"HEAT_LIMIT: %d",client_ui_status.shoot_heat_limit); HAL_Delay(15);
		ClientUI_DrawString("D05",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,720,"COOLING_RATE: %d",client_ui_status.shoot_cooling_rate); HAL_Delay(15);
		ClientUI_DrawString("D06",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,680,"AUTO_AIMING_FPS: %.2f",client_ui_status.auto_aiming_capture_fps); HAL_Delay(15);
		ClientUI_DrawString("D07",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,680,"BAT_VOLTAGE: %.2fV",client_ui_status.battery_voltage); HAL_Delay(15);
		ClientUI_DrawString("D08",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,640,"TEMP_BMI088: %.2f",client_ui_status.bmi088_temperature); HAL_Delay(15);
		ClientUI_DrawString("D09",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,620,"TEMP_CHIP: %.2f",client_ui_status.chip_temperature); HAL_Delay(15);
		ClientUI_DrawString("D10",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,600,"TEMP_CHASSIS1: %d",client_ui_status.motor_temperature[0]); HAL_Delay(15);
		ClientUI_DrawString("D11",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,580,"TEMP_CHASSIS2: %d",client_ui_status.motor_temperature[1]); HAL_Delay(15);
		ClientUI_DrawString("D12",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,560,"TEMP_CHASSIS3: %d",client_ui_status.motor_temperature[2]); HAL_Delay(15);
		ClientUI_DrawString("D13",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,20,540,"TEMP_CHASSIS4: %d",client_ui_status.motor_temperature[3]); HAL_Delay(15);
		ClientUI_DrawString("D14",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,640,"TEMP_GMIBAL_YAW: %d",client_ui_status.motor_temperature[4]); HAL_Delay(15);
		ClientUI_DrawString("D15",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,620,"TEMP_GMIBAL_PITCH: %d",client_ui_status.motor_temperature[5]); HAL_Delay(15);
		ClientUI_DrawString("D16",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,580,"TEMP_SHOOTER1: %d",client_ui_status.motor_temperature[6]); HAL_Delay(15);
		ClientUI_DrawString("D17",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,560,"TEMP_SHOOTER2: %d",client_ui_status.motor_temperature[7]); HAL_Delay(15);
		ClientUI_DrawString("D18",UI_OPERATE_UPDATE,1,UI_COLOR_YELLOW,270,540,"TEMP_TURNBULLET:  %d",client_ui_status.motor_temperature[8]); HAL_Delay(15);
}

void RefreshDynamicClientUI_Energy()
{

}



/***********************************************************************
** 函 数 名： RefreshClientUI()
** 函数说明： 刷新客户端UI界面
**---------------------------------------------------------------------
** 输入参数： UI显示控制标志位
** 返回参数： 无
***********************************************************************/
void RefreshClientUI(uint8_t *ui_show_flag)
{
	if(((*ui_show_flag) & 0x80) != 0) //刷新静态界面
	{
		if(((*ui_show_flag) & 0x01) != 0) //快速模式
		{
			RefreshStaticClientUI_Fast();
		}
		else if(((*ui_show_flag) & 0x02) != 0) //普通模式
		{
			RefreshStaticClientUI_Normal();
		}
		else if(((*ui_show_flag) & 0x04) != 0) //调试模式
		{
			RefreshStaticClientUI_Debug();
		}
		else if(((*ui_show_flag) & 0x08) != 0) //能量机关模式
		{
			RefreshStaticClientUI_Energy();
		}
		
		*ui_show_flag = (*ui_show_flag) & 0x7F;
	}
	else //刷新动态界面
	{
		if(((*ui_show_flag) & 0x01) != 0) //快速模式
		{
			RefreshDynamicClientUI_Fast();
		}
		else if(((*ui_show_flag) & 0x02) != 0) //普通模式
		{
			RefreshDynamicClientUI_Normal();
		}
		else if(((*ui_show_flag) & 0x04) != 0) //调试模式
		{
			RefreshDynamicClientUI_Debug();
		}
		else if(((*ui_show_flag) & 0x08) != 0) //能量机关模式
		{
			RefreshDynamicClientUI_Energy();
		}
	}
}

